﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Configuration;
using System.Xml.Linq;
using System.Text.RegularExpressions;

namespace FatusoAction
{
    public class FolderAndXMLAction
    {
        public static string RecuperaNomePastaVideo(string release, TipoVideo tipoVideo)
        {
            string releaseFiltro = FiltraCaracteres(release, false);
            if (tipoVideo == TipoVideo.Serie)
            {
                List<string> listaRegex = new List<string>(){ 
                @"S\d+E\d+",    //S00E00
                @"S\d+",        //S00
                @"\d+X\d+" };   //00x00

                int indexMatch = -1;
                foreach (string regex in listaRegex)
                {
                    Match match = Regex.Match(releaseFiltro.ToUpper(), regex);
                    if (match.Success)
                    {
                        indexMatch = match.Index;
                        break;
                    }
                }

                string nomeSerie = releaseFiltro.Substring(0, indexMatch).Trim();

                string SERIES_PATH = ConfigurationSettings.AppSettings["CaminhoXMLSeries"].ToString();
                XElement xml = XElement.Load(SERIES_PATH);
                List<XElement> elements = xml.Elements("Serie").ToList();

                foreach (XElement element in elements)
                {
                    List<string> sinonimos = new List<string>();
                    sinonimos.Add(element.Element("nome").Value);

                    List<XElement> filhosSinonimos = element.Elements("sinonimos").Elements("sinonimo").ToList();
                    foreach (XElement filho in filhosSinonimos)
                        sinonimos.Add(filho.Value);

                    foreach (string comp in sinonimos)
                    {
                        if (comp.ToUpper().Trim() == nomeSerie.ToUpper().Trim())
                        {
                            string pasta = element.Element("pasta").Value;
                            if (pasta != null && pasta.Trim() != "")
                                return pasta;
                        }
                    }
                }
                return ConfigurationSettings.AppSettings["CaminhoPastaDefault"].ToString();
            }
            else
            {
                return ConfigurationSettings.AppSettings["CaminhoPastaFilme"].ToString();
            }
        }

        public static string RecuperaIdPodnapisi(string nomeSerie)
        {
            string SERIES_PATH = ConfigurationSettings.AppSettings["CaminhoXMLSeriesPodnapisi"].ToString();
            XElement xml = XElement.Load(SERIES_PATH);
            List<XElement> elements = xml.Elements("Serie").ToList();

            foreach (XElement element in elements)
            {
                string elementNome = element.Element("nome").Value;

                if (elementNome.ToUpper().Trim() == nomeSerie.ToUpper().Trim())
                {
                    string resultado = element.Element("idPodnapisi").Value;
                    if (resultado != null && resultado.Trim() != "")
                        return resultado;
                }
            }
            return "";
        }

        public static bool SerieEquivalente(string releaseDigitado, string releaseEncontrado, TipoVideo tipoVideo)
        {
            if (tipoVideo == TipoVideo.Filme)
                return true;

            string releaseDigitadoFiltro = FiltraCaracteres(releaseDigitado, false);
            string releaseEncontradoFiltro = FiltraCaracteres(releaseEncontrado, false);

            List<string> listaRegex = new List<string>(){ 
                @"S\d+E\d+",    //S00E00
                @"S\d+",        //S00
                @"\d+X\d+" };   //00x00

            int indexMatchDigitado = -1;
            int indexMatchEncontrado = -1;
            bool encontrouDigitado = false;
            bool encontrouEncontrado = false;

            foreach (string regex in listaRegex)
            {
                Match matchDigitado = Regex.Match(releaseDigitadoFiltro.ToUpper(), regex);
                Match matchEncontrado = Regex.Match(releaseEncontradoFiltro.ToUpper(), regex);

                if (!encontrouDigitado && matchDigitado.Success)
                {
                    indexMatchDigitado = matchDigitado.Index;
                    encontrouDigitado = true;
                }

                if (!encontrouEncontrado && matchEncontrado.Success)
                {
                    indexMatchEncontrado = matchEncontrado.Index;
                    encontrouEncontrado = true;
                }

                if (encontrouDigitado && encontrouEncontrado) break;
            }
            string nomeSerieDigitada = releaseDigitadoFiltro.Substring(0, indexMatchDigitado).Trim();
            string nomeSerieEncontrado = releaseEncontradoFiltro.Substring(0, indexMatchEncontrado).Trim();

            string SERIES_PATH = ConfigurationSettings.AppSettings["CaminhoXMLSeries"].ToString();
            XElement xml = XElement.Load(SERIES_PATH);
            List<XElement> elements = xml.Elements("Serie").ToList();

            foreach (XElement element in elements)
            {
                List<string> sinonimos = new List<string>();
                sinonimos.Add(element.Element("nome").Value);

                List<XElement> filhosSinonimos = element.Elements("sinonimos").Elements("sinonimo").ToList();
                foreach (XElement filho in filhosSinonimos)
                    sinonimos.Add(filho.Value);

                foreach (string comp in sinonimos)
                {
                    //Verifica Digitado
                    string nomeXMLDigitado = "";
                    if (comp.ToUpper().Trim() == nomeSerieDigitada.ToUpper().Trim())
                        nomeXMLDigitado = element.Element("nome").Value;

                    //Verifica Encontrado
                    string nomeXMLEncontrado = "";
                    if (comp.ToUpper().Trim() == nomeSerieEncontrado.ToUpper().Trim())
                        nomeXMLEncontrado = element.Element("nome").Value;

                    //Compara as Duas
                    if (nomeSerieDigitada != "" && nomeSerieEncontrado != "" &&
                        nomeXMLDigitado != "" && nomeXMLEncontrado != "" &&
                        nomeXMLDigitado == nomeXMLEncontrado)
                        return true;
                    else if (nomeSerieEncontrado.ToUpper().Trim().Contains(nomeSerieDigitada.ToUpper().Trim()))
                        return true;
                }
            }
            return false;
        }

        public static List<string> RecuperaSeriesDownloadAutomatico(string parametros)
        {
            string SERIES_PATH = ConfigurationSettings.AppSettings["CaminhoXMLSeries"].ToString();
            XElement xml = XElement.Load(SERIES_PATH);
            List<XElement> elements = xml.Elements("Serie").ToList();

            return new List<string>();
        }

        public static List<string> RecuperaSeriesPossiveis(string release)
        {
            List<KeyValuePair<string, int>> comparacao = new List<KeyValuePair<string, int>>();
            string releaseFiltro = FiltraCaracteres(release, false);
            List<string> listaRegex = new List<string>(){ 
                @"S\d+E\d+",    //S00E00
                @"S\d+",        //S00
                @"\d+X\d+" };   //00x00

            int indexMatch = -1;
            foreach (string regex in listaRegex)
            {
                Match match = Regex.Match(releaseFiltro.ToUpper(), regex);
                if (match.Success)
                {
                    indexMatch = match.Index;
                    break;
                }
            }
            string nomeSerie = "";
            if (indexMatch > 0)
                nomeSerie = releaseFiltro.Substring(0, indexMatch).Trim();
            else
                return new List<string>();

            string SERIES_PATH = ConfigurationSettings.AppSettings["CaminhoXMLSeries"].ToString();
            XElement xml = XElement.Load(SERIES_PATH);
            List<XElement> elements = xml.Elements("Serie").ToList();

            foreach (XElement element in elements)
            {
                List<string> sinonimos = new List<string>();
                string nome = element.Element("nome").Value;
                sinonimos.Add(nome);

                List<XElement> filhosSinonimos = element.Elements("sinonimos").Elements("sinonimo").ToList();
                foreach (XElement filho in filhosSinonimos)
                    sinonimos.Add(filho.Value);

                List<KeyValuePair<string, int>> comparacaoTemp = new List<KeyValuePair<string, int>>();
                foreach (string comp in sinonimos)
                {
                    int distancia = StringDistance.EditDistance(comp, nomeSerie);
                    if (comp.ToUpper().Trim() == nomeSerie.ToUpper().Trim())
                    {
                        return new List<string>() { nome };
                    }
                    else if (
                        (nomeSerie.Length > 4 || !nomeSerie.ToUpper().StartsWith("THE"))
                        &&
                        (comp.ToUpper().Trim().Contains(nomeSerie.ToUpper().Trim()) ||
                        nomeSerie.ToUpper().Trim().Contains(comp.ToUpper().Trim())))
                    {
                        comparacaoTemp.Add(new KeyValuePair<string, int>(comp, 99));
                    }
                    else
                    {
                        int porcentagem = Convert.ToInt32(((1.0 - (1.0 * distancia / comp.Length)) * 100));
                        if (porcentagem < 0) porcentagem = 0;
                        comparacaoTemp.Add(new KeyValuePair<string, int>(comp, porcentagem));
                    }

                }
                comparacao.Add(new KeyValuePair<string, int>(nome, comparacaoTemp.Max(c => c.Value)));
            }
            List<KeyValuePair<string, int>> compRetorno = comparacao.Where(c => c.Value > 50).OrderBy(c => c.Value).Reverse().Take(10).ToList();
            return compRetorno.Select(c => c.Key).ToList();
        }

        public static string RecuperaTagEpisodio(string release, bool manterPosTag)
        {
            List<KeyValuePair<string, int>> comparacao = new List<KeyValuePair<string, int>>();
            string releaseFiltro = FiltraCaracteres(release, false);
            List<string> listaRegex = new List<string>(){ 
                @"S\d+E\d+",    //S00E00
                @"S\d+",        //S00
                @"\d+X\d+" };   //00x00

            foreach (string regex in listaRegex)
            {
                Match match = Regex.Match(releaseFiltro.ToUpper(), regex);
                if (match.Success)
                {
                    if (manterPosTag)
                        return releaseFiltro.Substring(match.Index).ToUpper();
                    else
                        return match.Groups[0].Value.ToUpper();
                }
            }
            return "";
        }

        public static string RecuperaTagFilme(string release, TipoRetornoTag tipoRetornoTag)
        {
            List<KeyValuePair<string, int>> comparacao = new List<KeyValuePair<string, int>>();
            string releaseFiltro = release;// RecuperaReleaseFiltrado(release);
            List<string> listaRegex = new List<string>() { @"\(\d+\)" };

            foreach (string regex in listaRegex)
            {
                Match match = Regex.Match(releaseFiltro.ToUpper(), regex);
                if (match.Success)
                {
                    switch (tipoRetornoTag)
                    {
                        case TipoRetornoTag.Tag:
                            return match.Groups[0].Value;
                        case TipoRetornoTag.PosTag:
                            return releaseFiltro.Substring(match.Index).Replace(match.Groups[0].Value, "").Trim();
                            break;
                        case TipoRetornoTag.RetornaAmbos:
                            return releaseFiltro.Substring(match.Index);
                    }
                }
            }
            return "";
        }

        public static string RecuperaNomeSerie(string release)
        {
            string releaseFiltro = FiltraCaracteres(release, false);
            List<string> listaRegex = new List<string>(){ 
                @"S\d+E\d+",    //S00E00
                @"S\d+",        //S00
                @"\d+X\d+" };   //00x00

            int indexMatch = -1;
            foreach (string regex in listaRegex)
            {
                Match match = Regex.Match(releaseFiltro.ToUpper(), regex);
                if (match.Success)
                {
                    indexMatch = match.Index;
                    break;
                }
            }
            if (indexMatch > 0)
            {
                string nomeSerie = releaseFiltro.Substring(0, indexMatch).Trim();
                return nomeSerie;
            }
            return releaseFiltro;
        }

        public static string FiltraCaracteres(string name, bool folderOnly)
        {
            var builder = new StringBuilder();
            var invalid = System.IO.Path.GetInvalidFileNameChars();
            foreach (char cur in name)
            {
                if (!invalid.Contains(cur))
                    builder.Append(cur);
                else
                    builder.Append(' ');
            }
            string retorno = builder.ToString();
            if (!folderOnly)
            {
                retorno = retorno.Replace('.', ' ').Replace('-', ' ').Replace('_', ' ');
                retorno = retorno.Replace('(', ' ').Replace(')', ' ').Replace('[', ' ');
                retorno = retorno.Replace(']', ' ').Replace('{', ' ').Replace('}', ' ');
            }

            while (retorno.IndexOf("  ") > 0)
                retorno = retorno.Replace("  ", " ");

            return retorno;
        }
    }
}
